/*
* @version: 1.2
* @Author:  tomato
* @Date:    2018-4-24 22:56:00
* @Last Modified by:   tomato
* @Last Modified time: 2018-5-26 18:08:43
*/
//无限级下拉框
layui.define(['jquery', 'form'], function(exports){
    var MOD_NAME = 'selectN';
    var $ = layui.jquery;
    var form = layui.form;
    var obj = function(config){
        //当前选中数据值名数据
        this.selected =[];
        //当前选中的值
        this.values = [];
        //当前选中的名
        this.names = [];
        //当前选中最后一个值
        this.lastValue = '';
        //当前选中最后一个值
        this.lastName = '';
        //是否已选
        this.isSelected = false;
        //初始化配置
        this.config = {
            //选择器id或class
            elem: '',
            //无限级分类数据
            data: [],
            //默认选中值
            selected: [],
            //空值项提示，可设置为数组['请选择省','请选择市','请选择县']
            tips: '请选择',
            //是否允许搜索，可设置为数组[true,true,true]
            search:false,
            //选择项宽度，可设置为数组['80','90','100']
            width:null,
            //为真只取最后一个值
            last: false,
            //值验证，与lay-verify一致
            verify: '',
            //事件过滤器，lay-filter名
            filter: '',
            //input的name 不设置与选择器相同(去#.)
            name: '',
            //数据分隔符
            delimiter: ',',
            //数据的键名 status=0为禁用状态
            field:{idName:'id',titleName:'name',statusName:'status',childName:'children'},
            //多表单区分 form.render(type, filter); 为class="layui-form" 所在元素的 lay-filter="" 的值
            formFilter: null
        }

        //实例化配置
        this.config = $.extend(this.config,config);

        //“请选择”文字
        this.setTips = function(){
            var o = this,c = o.config;
            if(Object.prototype.toString.call(c.tips)!='[object Array]'){
                return c.tips;
            }
            else{
                var i=$(c.elem).find('select').length;
                return c.tips.hasOwnProperty(i) ? c.tips[i] : '请选择';
            }
        }

        //设置是否允许搜索
        this.setSearch = function(){
            var o = this,c = o.config;
            if(Object.prototype.toString.call(c.search)!='[object Array]'){
                return c.search===true ? 'lay-search ' : ' ';
            }
            else{
                var i=$(c.elem).find('select').length;
                if(c.search.hasOwnProperty(i)){
                    return c.search[i]===true ? 'lay-search ' : ' ';
                }
            }
            return ' ';
        }

        //设置是否允许搜索
        this.setWidth = function(){
            var o = this,c = o.config;
            if(Object.prototype.toString.call(c.width)!='[object Array]'){
                return /^\d+$/.test(c.width) ? 'style="width:'+c.width+'px;" ' : ' ';
            }
            else{
                var i=$(c.elem).find('select').length;
                if(c.width.hasOwnProperty(i)){
                    return /^\d+$/.test(c.width[i]) ? 'style="width:'+c.width[i]+'px;" ' : ' ';
                }
            }
        }

        //创建一个Select
        this.createSelect = function(optionData){
            var o = this,c = o.config,f=c.field;
            var html = '';
            html+= '<div class="layui-input-inline" '+o.setWidth()+'>';
            html+= ' <select '+o.setSearch()+'lay-filter="'+c.filter+'">';
            html+= '  <option value="">'+o.setTips()+'</option>';
            for(var i=0;i<optionData.length;i++){
                var disabled = optionData[i][f.statusName]==0 ? 'disabled="" ' : '';
                html+= '  <option '+disabled+'value="'+optionData[i][f.idName]+'">'+optionData[i][f.titleName]+'</option>';
            }
            html+= ' </select>';
            html+= '</div>';
            return html;
        };

        //获取当前option的数据
        this.getOptionData=function(catData,optionIndex){
            var f = this.config.field;
            var item = catData;
            for(var i=0;i<optionIndex.length;i++){
                if('undefined' == typeof item[optionIndex[i]]){
                    item = null;
                    break;
                }
                else if('undefined' == typeof item[optionIndex[i]][f.childName]){
                    item = null;
                    break;
                }
                else{
                    item = item[optionIndex[i]][f.childName];
                }
            }
            return item;
        };

        //初始化
        this.set = function(selected){
            var o = this,c = o.config;
            $E = $(c.elem);
            //创建顶级select
            var verify = c.verify=='' ? '' : 'lay-verify="'+c.verify+'" ';
            var html = '<div style="height:0px;width:0px;overflow:hidden"><input '+verify+'name="'+c.name+'"></div>';
            html += o.createSelect(c.data);
            $E.html(html);
            selected = typeof selected=='undefined' ? c.selected : selected;
            var index=[];
            for(var i=0;i<selected.length;i++){
                //设置最后一个select的选中值
                $E.find('select:last').val(selected[i]);
                //获取该选中值的索引
                var lastIndex = $E.find('select:last').get(0).selectedIndex-1;
                index.push(lastIndex);
                //取出下级的选项值
                var childItem = o.getOptionData(c.data,index);
                //下级选项值存在则创建select
                if(childItem){
                    var html = o.createSelect(childItem);
                    $E.append(html);
                }
            }
            form.render('select',c.formFilter);
            o.getSelected();
        };

        //下拉事件
        this.change = function(elem){
            var o = this,c = o.config;
            var $thisItem = elem.parent();
            //移除后面的select
            $thisItem.nextAll('div.layui-input-inline').remove();
            var index=[];
            //获取所有select，取出选中项的值和索引
            $thisItem.parent().find('select').each(function(){
                index.push($(this).get(0).selectedIndex-1);
            });

            var childItem = o.getOptionData(c.data,index);
            if(childItem){
                var html = o.createSelect(childItem);
                $thisItem.after(html);
                form.render('select',c.formFilter);
            }
            o.getSelected();
        };

        //获取所有值-数组 每次选择后执行
        this.getSelected=function(){
            var o = this,c = o.config;
            var values =[];
            var names =[];
            var selected =[];
            $E = $(c.elem);
            $E.find('select').each(function(){
                var item = {};
                var v = $(this).val()
                var n = $(this).find('option:selected').text();
                item.value = v;
                item.name = n;
                values.push(v);
                names.push(n);
                selected.push(item);
            });
            o.selected =selected;
            o.values = values;
            o.names = names;
            o.lastValue = $E.find('select:last').val();
            o.lastName = $E.find('option:selected:last').text();

            o.isSelected = o.lastValue=='' ? false : true;
            var inputVal = c.last===true ? o.lastValue : o.values.join(c.delimiter);
            $E.find('input[name="'+c.name+'"]').val(inputVal);
        };
        //ajax方式获取候选数据
        this.getData = function(url){
            var d;
            $.ajax({
                url:url,
                dataType:'json',
                async:false,
                success:function(json){
                    d=json;
                },
                error: function(){
                    console.error(MOD_NAME+' hint：候选数据ajax请求错误 ');
                    d = false;
                }
            });
            return d;
        }


    };

    //渲染一个实例
    obj.prototype.render = function(){
        var o=this,c=o.config;
        $E = $(c.elem);
        if($E.length==0){
            console.error(MOD_NAME+' hint：找不到容器 '+c.elem);
            return false;
        }
        if(Object.prototype.toString.call(c.data)!='[object Array]'){
            var data = o.getData(c.data);
            if(data===false){
                console.error(MOD_NAME+' hint：缺少分类数据');
                return false;
            }
            o.config.data =  data;
        }

        c.filter = c.filter=='' ? c.elem.replace('#','').replace('.','') : c.filter;
        c.name = c.name=='' ? c.elem.replace('#','').replace('.','') : c.name;
        o.config = c;

        //初始化
        o.set();

        //监听下拉事件
        form.on('select('+c.filter+')',function(data){
            o.change($(data.elem));
        });
        //验证失败样式
        $E.find('input[name="'+c.name+'"]').focus(function(){
            var t = $(c.elem).offset().top;
            $('html,body').scrollTop(t-200);
            $(c.elem).find('select:last').addClass('layui-form-danger');
            setTimeout(function(){
                $(c.elem).find('select:last').removeClass('layui-form-danger');
            },3000);
        });
    }

    //输出模块
    exports(MOD_NAME, function (config) {
        var _this = new obj(config);
        _this.render();
        return _this;
    });
});